/**
 * 
 */
package lt.vin.exaatto.server.service.impl;

import java.util.Collection;
import java.util.Set;

import lt.vin.exaatto.server.ParsedJid;
import lt.vin.exaatto.server.dao.ChatDao;
import lt.vin.exaatto.server.service.ChatService;
import lt.vin.exaatto.shared.Chat;

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.inject.Inject;

/**
 * @author Vincentas
 *
 */
public class ChatServiceImpl implements ChatService {
	
	private static final String SERVICE_HOME_URL = "http://exa-atto.appspot.com";

	@Inject XMPPService xmppService;
	
	@Inject ChatDao chatDao;

	@Override
	public void handle(Message receivedMessage) {
		ParsedJid sender = ParsedJid.parse(receivedMessage.getFromJid());
		ParsedJid recipient = ParsedJid.parse(receivedMessage.getRecipientJids()[0]);		
		String messageText = receivedMessage.getBody();
		
		Chat chat = getChatDao().get(recipient.getNode());
				
		Message message;
		
		if (chat == null) {
			chat = new Chat(recipient.getNode(), sender.getAddress());
			getChatDao().save(chat);
			
			message = new MessageBuilder().
				withRecipientJids(sender.getJid()).
				withFromJid(recipient.getJid()).
				withBody("Welcome to your new group chat : " + chat.getName() + ". For more information visit " + SERVICE_HOME_URL + " or send lots of ?????????...").
				build();
		} else {
			if (chat.isMember(sender.getAddress())) {
				if (isCryForHelp(messageText)) {
					message = new MessageBuilder().
						withRecipientJids(sender.getJid()).
						withFromJid(recipient.getJid()).
						withBody("*[" + chat.getName() + "]* Visit " + SERVICE_HOME_URL + " for more information").
						build();
				} else {
					if (chat.getAllMembers().size() < 2) {
						message = new MessageBuilder().
							withRecipientJids(sender.getJid()).
							withFromJid(recipient.getJid()).
							withBody("*[" + chat.getName() + "]* No more participants yet. Visit " + SERVICE_HOME_URL + " to manage this chat.").
							build();
					} else {
						Set<String> members = chat.getAllMembers();
						members.remove(sender.getAddress().toLowerCase());
						
						message = new MessageBuilder().
							withRecipientJids(toJidArray(members)).
							withFromJid(recipient.getJid()).
							withBody("*[" + sender.getNode() + "]* " + messageText).
							build();					
					}
				}
			} else {
				message = new MessageBuilder().
					withRecipientJids(sender.getJid()).
					withFromJid(recipient.getJid()).
					withBody("You are not a member of this chat").
					build();
			}
		}
		
		getXmppService().sendMessage(message);
	}
	
	@Override
	public void invite(String member, String from) {
		getXmppService().sendInvitation(new JID(member), new JID(from));
	}

	private boolean isCryForHelp(String message) {
		return message.matches("\\?{3,}+");
	}

	private JID[] toJidArray(Collection<String> recipients) {
		JID[] result = new JID[recipients.size()];

		int i = 0;
		for (String recipient : recipients) {
			result[i++] = new JID(recipient);
		}
		
		return result;
	}

	/**
	 * @return the xmppService
	 */
	public XMPPService getXmppService() {
		return xmppService;
	}

	/**
	 * @param xmppService the xmppService to set
	 */
	public void setXmppService(XMPPService xmppService) {
		this.xmppService = xmppService;
	}

	/**
	 * @return the chatDao
	 */
	public ChatDao getChatDao() {
		return chatDao;
	}

	/**
	 * @param chatDao the chatDao to set
	 */
	public void setChatDao(ChatDao chatDao) {
		this.chatDao = chatDao;
	}
}
